热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

驼峰|篇幅_JetpackDataStore你总要了解一下吧?

篇首语:本文由编程笔记#小编为大家整理,主要介绍了Jetpack DataStore 你总要了解一下吧?相关的知识,希望对你有一定的参考价值。 目录 一、DataStore 介绍 Preference

篇首语:本文由编程笔记#小编为大家整理,主要介绍了Jetpack DataStore 你总要了解一下吧?相关的知识,希望对你有一定的参考价值。


目录

一、DataStore 介绍

Preferences DataStore 和 Proto DataStore

二、Preferences DataStore

2.1 添加依赖

2.2 使用 Preferences DataStore 存储键值对

2.2.1 创建 DataStore

2.2.1 DataStore 写入数据

2.2.3 DataStore 读取数据

三、Proto DataStore

3.1 定义架构

3.2 创建 Proto DataStore

四、相关链接




一、DataStore 介绍

        DataStore 是 android Jetpack 中的一个组件,它是一个数据存储的解决方案,跟 SharedPreferences 一样,采用key-value形式存储。

        DataStore 保证原子性,一致性,隔离性,持久性。尤其是,它解决了 SharedPreferences API 的设计缺陷。

        Jetpack DataStore 是经过改进的新版数据存储解决方案,旨在取代 SharedPreferences,让应用能够以异步、事务方式存储数据。



注意:DataStore 比较适合小数据和简单操作,并且无法局部的更新数据。如果你需要支持大型或复杂的数据集、部分更新或引用完整性,请考虑使用 Room 而不是 DataStore。



Preferences DataStore 和 Proto DataStore


  • Preferences DataStore:与SharedPreferences类似,通过键值对存储数据,此实现不需要预定义模式,也不提供类型安全。

  • Proto DataStore:通过Protocol-Buffers定义存储数据类型以及结构,保证类型安全。

        本文重点了解Preferences DataStore。


二、Preferences DataStore

        与SharedPreferences类似,通过键值对存储数据,此实现不需要预定义模式,也不提供类型安全。


2.1 添加依赖

        在你项目的app_module对应的build.gradle中添加如下依赖:

dependencies 
    //Typed DataStore (Typed API surface, such as Proto)
    implementation "androidx.datastore:datastore:1.0.0"
//    //可选 - RxJava2 support
//    implementation "androidx.datastore:datastore-rxjava2:1.0.0"
//    //可选 - RxJava3 support
    implementation "androidx.datastore:datastore-rxjava3:1.0.0"
    
    //Preferences DataStore (SharedPreferences like APIs)
    implementation "androidx.datastore:datastore-preferences:1.0.0"
//    // 可选 - RxJava2 support
//    implementation "androidx.datastore:datastore-preferences-rxjava2:1.0.0"
//    // 可选 - RxJava3 support
    implementation "androidx.datastore:datastore-preferences-rxjava3:1.0.0"

2.2 使用 Preferences DataStore 存储键值对

        首先看看 DataStore 源码,DataStore 是一个接口。

package androidx.datastore.core
import kotlinx.coroutines.flow.Flow
import java.io.IOException
/**
 * DataStore数据存储提供了一种安全、持久的方式来存储少量数据,如 preferences 和应用程序状态。
 * 数据存储提供了ACID保证。它是线程安全的,并且不阻塞。特别是,它解决了SharedReferences API的这些设计缺陷:
 * 1. Synchronous API encourages StrictMode violations
 * 2. apply() and commit() have no mechanism of signalling errors
 * 3. apply() will block the UI thread on fsync()
 * 4. Not durable – it can returns state that is not yet persisted
 * 5. No consistency or transactional semantics
 * 6. Throws runtime exception on parsing errors
 * 7. Exposes mutable references to its internal state
 */
public interface DataStore 
    public val data: Flow
    public suspend fun updateData(transform: suspend (t: T) -> T): T

以上可以看出 DataStore 是基于 协程 和 Flow 实现的。


  • data 是一个 Flow 对象。

  • updateData() 用于更新对象。

        并且查看 DataStore 的其他相关源码你会发现他们都是基于Kotlin语言开发。Google 对于推 Kotlin 那是相当执着。


2.2.1 创建 DataStore


  • 使用 preferencesDataStore(Kotlin) 创建Datastore 的实例。

  • 如果你使用 RxJava,要使用 RxPreferenceDataStoreBuilder。

        必需的 name 参数是 Preferences DataStore 的名称。

        这里我们使用的是RxJava:

        RxDataStore dataStore =
                new RxPreferenceDataStoreBuilder(this, /*name=*/ "datastore_sc").build();
        //创建使用的key
        Preferences.Key nameKey = PreferencesKeys.stringKey("name");
        Preferences.Key ageKey = PreferencesKeys.intKey("age");

        默认路径:/data/data/com.scc.datastorage/files/datastore/datastore_sc.preferences_pb

        这里创建了两个key,分别是 String 类型和 Int 类型。


2.2.1 DataStore 写入数据

    //关于 nameKey 和 ageKey 请看上面代码。
    putString(nameKey, "name-Scc");
    putInteger(ageKey, 25);    
    
    //2022/1/25 功能:存入String类型的数据
    private void putString(Preferences.Key nameKey, String value) 
        dataStore.updateDataAsync(new Function>() 
            @Override
            public Single apply(Preferences preferences) throws Throwable 
                MutablePreferences mutablePreferences = preferences.toMutablePreferences();
                mutablePreferences.set(nameKey, value);
                return Single.just(mutablePreferences);
            
        );
    
    //2022/1/25 功能:存入Integer类型的数据
    private void putInteger(Preferences.Key ageKey, Integer value) 
        dataStore.updateDataAsync(new Function>() 
            @Override
            public Single apply(Preferences preferences) throws Throwable 
                MutablePreferences mutablePreferences = preferences.toMutablePreferences();
                mutablePreferences.set(ageKey, value);
                return Single.just(mutablePreferences);
            
        );
    

        这里写入的两种类型,这样更加仿版理解和你写成自己的工具类,因为使用 DataStore 比较少实践少就不提供工具类了,以免误导大家。


2.2.3 DataStore 读取数据

    getString(nameKey);
    getInteger(ageKey);
    
    //2022/1/25 功能:获取String类型数据
    private void getString(Preferences.Key nameKey) 
        Log.e("DataStore", nameKey.toString());
        Flowable example = dataStore.data().map(new Function() 
            @Override
            public String apply(Preferences preferences) 
                Log.e("DataStore.apply", preferences.get(nameKey));
                return preferences.get(nameKey);
            
        );
        Log.e("DataStore.Flowable", example.first("default").blockingGet());
    
    //2022/1/25 功能:获取Integer类型数据
    private void getInteger(Preferences.Key ageKey) 
        Log.e("DataStoreKey", ageKey.toString());
        Flowable example = dataStore.data().map(new Function() 
            @Override
            public Integer apply(Preferences preferences) 
                Log.e("DataStore.apply", preferences.get(ageKey).intValue() + "");
                return preferences.get(ageKey);
            
        );
        Log.e("DataStore.Flowable", example.first(12).blockingGet().toString());
    


三、Proto DataStore

        通过Protocol-Buffers定义存储数据类型以及结构,保证类型安全。

        Proto DataStore 实现使用 DataStore 和 Protocol-Buffers 将类型化对象持久保存到磁盘。

什么是 Protocol-Buffers?

        Protocol-Buffers是谷歌的语言中立、平台中立、可扩展的机制,用于序列化结构化数据——比如XML,但更小、更快、更简单。您只需定义一次数据的结构化方式,然后就可以使用特殊生成的源代码,轻松地在各种数据流之间以及使用各种语言编写和读取结构化数据。


3.1 定义架构

        Proto DataStore 需要app/src/main/proto/目录中的 proto 文件中的预定义模式。此架构定义了您在 Proto DataStore 中持久保存的对象的类型。

syntax = "proto3";
option java_multiple_files = true;
option java_package = "com.scc.datastorage.proto";
option java_outer_classname = "User";
message User
  string name = 1;
  int32 age = 2;

.proto 文件以包声明开头,这有助于防止不同项目之间的命名冲突。


  • java_multiple_files:可以为每个生成的类生成一个单独的 .java 文件。

  • java_package:指定生成的类应该使用什么 Java 包名称。如果您没有明确指定,它只会匹配包声明给出的包名。

  • java_outer_classname:定义了类名。如果没有设置这个 options ,它将通过将文件名转换为大写驼峰式来生成。例如,默认情况下,“my_proto.proto”将使用“MyProto”作为包装类名称。

定义 message:


  • 可以使用许多标准的简单数据类型可用作字段类型,包括 bool、int32、float、double 和 string。

  • 还可以通过使用其他 message 类型作为字段类型来为你的消息添加进一步的结构。

        每个元素上的 "= 1"、"= 2" 标记标识该字段在二进制编码中使用的唯一 "tag"

        更多关于 的内容可以去官网找找 protobuf 语言指南。



注意:存储对象的类是在编译时从 proto 文件中定义的message生成的。确保你 rebuild 你的项目。



3.2 创建 Proto DataStore


  • 1.定义一个实现 Serializer 的类,其中 T 是 proto 文件中定义的类型。

  • 2.使用 dataStore 创建的属性委托来创建 DataStore 的实例,其中 T 是 proto 文件中定义的类型。

        写到这里 proto 文件中定义的类无法生成,也尝试了很多办法,不知道什么情况。后续步骤可参照官网,其他方法和Preferences DataStore类似。就不占用篇幅了。


四、相关链接

官方文档 DataStore

        个人感觉 DataStore 还没有 SP 和 MMKV 好用,推荐使用 MMKV 毕竟上线好几年了,而且是大厂推出,相对稳定一些,有些个人自己实现了 SP 的功能,但是万一有 Bug 或者突然不继续维护了是不是就尴尬了。

 

 


推荐阅读
  • EasyMock实战指南
    本文介绍了如何使用EasyMock进行单元测试,特别是当测试对象的合作者依赖于外部资源或尚未实现时。通过具体的示例,展示了EasyMock在模拟对象行为方面的强大功能。 ... [详细]
  • MySQL锁机制详解
    本文深入探讨了MySQL中的锁机制,包括表级锁、行级锁以及元数据锁,通过实例详细解释了各种锁的工作原理及其应用场景。同时,文章还介绍了如何通过锁来优化数据库性能,避免常见的并发问题。 ... [详细]
  • 前言无论是对于刚入行工作还是已经工作几年的java开发者来说,面试求职始终是你需要直面的一件事情。首先梳理自己的知识体系,针对性准备,会有事半功倍的效果。我们往往会把重点放在技术上 ... [详细]
  • 深入解析IGMP各版本特性及其演进
    本文详细探讨了Internet组管理协议(IGMP)的不同版本,包括IGMPv1的基础功能、IGMPv2的增强特性和IGMPv3的重要改进。特别分析了IGMPv3如何支持特定源组播(SSM)模型,并介绍了各版本之间的主要差异。 ... [详细]
  • 初探Java编程:从入门到实践
    本文旨在为初学者提供Java编程的基础知识,涵盖程序、算法、流程图的概念,以及JDK环境的配置和Eclipse的使用方法。 ... [详细]
  • YB02 防水车载GPS追踪器
    YB02防水车载GPS追踪器由Yuebiz科技有限公司设计生产,适用于车辆防盗、车队管理和实时追踪等多种场合。 ... [详细]
  • Java与JSON互转:实现JSON到Java对象及Java对象到JSON的转换
    本文详细介绍了如何在Java中实现JSON数据与Java对象之间的相互转换,包括代码示例和常见问题解决方法。 ... [详细]
  • 本文探讨了如何利用SqlDependency执行复杂的SQL查询,并确保在多线程环境下的安全性与效率。 ... [详细]
  • Python数据类型6 字典
    字典Python的字典数据类型是基于hash散列算法实现的,采用键值对(key:value)的形式,根据key的值计算value的地址,具有非常快的查取和插入速度。但它是无序的,包 ... [详细]
  • 题目 CF1245F: 清理春天的数学挑战 描述了一个数学问题:给定一个区间 [L, R](0 ≤ L, R ≤ 10^9),求该区间内满足 x + y = x ∧ y 的数对 (x, y) 的总数。 ... [详细]
  • 本文深入探讨了JavaScript中实现继承的四种常见方法,包括原型链继承、构造函数继承、组合继承和寄生组合继承。对于正在学习或从事Web前端开发的技术人员来说,理解这些继承模式对于提高代码质量和维护性至关重要。 ... [详细]
  • 微信小程序中实现位置获取的全面指南
    本文详细介绍了如何在微信小程序中实现地理位置的获取,包括通过微信官方API和腾讯地图API两种方式。文中不仅涵盖了必要的准备工作,如申请开发者密钥、下载并配置SDK等,还提供了处理用户授权及位置信息获取的具体代码示例。 ... [详细]
  • 本文详细介绍了在使用Socket进行网络编程时,遇到链接器错误`undefined reference to WSAStartup@8`的解决方案,适用于多种开发环境。 ... [详细]
  • 本文探讨了Web开发与游戏开发之间的主要区别,旨在帮助开发者更好地理解两种开发领域的特性和需求。文章基于作者的实际经验和网络资料整理而成。 ... [详细]
  • NFS(Network File System)即网络文件系统,是一种分布式文件系统协议,主要用于Unix和类Unix系统之间的文件共享。本文详细介绍NFS的配置文件/etc/exports和相关服务配置,帮助读者理解如何在Linux环境中配置NFS客户端。 ... [详细]
author-avatar
繁華落盡灬熙
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有